namespace Brjnk.GpxExplorer.Workspace
{
    using Brjnk.GpxExplorer.ViewModel;
    using Brjnk.GpxExplorer.Workspace.Searching;

    /// <summary>
    /// </summary>
    public class GraphDataAdapter : DataAdapter
    {
        public GraphDataAdapter(DataModel model, SearchService searchService, DataView view)
            : base(model, searchService, view)
        {
            base.Thickness = 1;
        }

        private bool showPhotos;

        public bool ShowPhotos
        {
            get { return showPhotos; }
            set
            {
                showPhotos = value; Invalidate(DataAdapterItemType.SearchPhotoResult);
            }
        }

        private bool showSearchResults;

        public bool ShowSearchResults
        {
            get { return showSearchResults; }
            set
            {
                showSearchResults = value;
                Invalidate(DataAdapterItemType.SearchTimeResult);
                Invalidate(DataAdapterItemType.SearchPositionResult);
            }
        }

        private bool showWaypoints;

        public bool ShowWaypoints
        {
            get { return showWaypoints; }
            set
            {
                showWaypoints = value;
                Invalidate(DataAdapterItemType.SearchWaypointResult);
            }
        }

        private TrackPointAttributeInfo yAttribute;

        public TrackPointAttributeInfo YAttribute
        {
            get { return yAttribute; }
            set { yAttribute = value; Invalidate(); }
        }

        private TrackPointAttributeInfo xAttribute;

        public TrackPointAttributeInfo XAttribute
        {
            get { return xAttribute; }
            set { xAttribute = value; Invalidate(); }
        }

        private bool xJoined;

        public bool XJoined
        {
            get { return xJoined; }
            set { xJoined = value; Invalidate(); }
        }

        protected override System.Windows.Point? GetSearchRequestPosition(SearchRequest request)
        {
            return null;
        }

        protected override System.Windows.Point? GetSearchResultPosition(SearchResult result)
        {
            var track = result.FoundIn as TrackVM;
            if (track == null) return null;

            if (!showPhotos && result.SearchedItem is LocatedPhoto) return null;
            if (!showWaypoints && result.SearchedItem is WaypointVM) return null;
            if (!showSearchResults && result.SearchedItem is SearchRequest) return null;
            return GetValue(track, (TrackPointVM)result.OriginalResult.PreviousPoint, (TrackPointVM)result.OriginalResult.NextPoint, result.OriginalResult.Parameter);
        }

        protected override System.Windows.Point? GetPhotoPosition(ViewModel.LocatedPhoto photo)
        {
            return null;
        }

        protected override System.Windows.Point? GetWaypointPosition(ViewModel.WaypointVM waypoint)
        {
            return null;
        }

        protected override System.Windows.Point? GetTrackPointPosition(TrackVM track, ViewModel.TrackPointVM previous, ViewModel.TrackPointVM current, ViewModel.TrackPointVM next)
        {
            if (YAttribute.Type == TrackPointAttributeType.Type2)
            {
                if (previous == null && next != null) GetValue(track, next);
                return GetValue(track, current);
            }
            else
            {
                return GetValue(track, current);
            }
        }

        private System.Windows.Point? GetValue(TrackVM track, TrackPointVM previous, TrackPointVM next, double p)
        {
            var x = track.GetAttributeValue(XAttribute, XJoined, previous, next, p, false);
            var y = track.GetAttributeValue(YAttribute, base.IncludeGaps, previous, next, p, false);
            if (!x.HasValue || !y.HasValue) return null;
            return new System.Windows.Point(x.Value, y.Value);
        }

        private System.Windows.Point? GetValue(TrackVM track, TrackPointVM point)
        {
            var y = point.GetAttributeValue(YAttribute, base.IncludeGaps, false);
            var x = point.GetAttributeValue(XAttribute, XJoined, false);
            if (!x.HasValue || !y.HasValue) return null;
            return new System.Windows.Point(x.Value, y.Value);
        }

        protected override System.Windows.Point? GetRoutePointPosition(RouteVM route, ViewModel.RoutePointVM previous, ViewModel.RoutePointVM current, ViewModel.RoutePointVM next)
        {
            return null;
        }

        protected override CoordinateSystem2D.AxisOrientation? GetGraphConstantInfo(ViewModel.RouteVM route)
        {
            return null;
        }

        protected override CoordinateSystem2D.AxisOrientation? GetGraphConstantInfo(ViewModel.TrackVM route)
        {
            if (YAttribute.Type == TrackPointAttributeType.Type2) return CoordinateSystem2D.AxisOrientation.Horizontal;
            return null;
        }
    }
}